home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 338_01 / asetc.c < prev    next >
Text File  |  1988-02-23  |  11KB  |  427 lines

  1. /* asetc.c - misc routines
  2.  * parse statement for label and instruction, find operand field
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <ctype.h>
  7. #include "as68.h"
  8.  
  9. /* state types */
  10. #define    START 1
  11. #define    LBL 2
  12. #define    LIM 3
  13. #define    STOP 4
  14.  
  15. /* character types */
  16. #define    LIM_C 1
  17. #define    LM_C 2
  18. #define    LBLTRM_C 3
  19. #define    WS_C 4
  20. #define    STMEND_C 5
  21. #define    CMNT_C 6
  22. #define    ILGL_C 7
  23.  
  24. extern char *stmnt_ptr;        /* moved to root */
  25. extern char statement[STMNT_SIZE];
  26. extern char instr[32];
  27. extern char label[32];
  28. extern char *opfld_ptr;
  29. extern char lcksm;
  30. extern char pass;
  31. extern int src_level;
  32. extern int loc_plus;
  33. extern int wrap;
  34. extern unsigned line_count;
  35. extern long loc_counter;
  36. extern FLAG nolist;
  37. extern FLAG lcon;
  38. extern FLAG llst;
  39. extern FLAG lfile;
  40. extern FLAG obj_open;
  41. extern FLAG trunc;
  42. extern FILE *_src[SRCLEVELS];
  43. extern FILE *lst_d;
  44. extern FILE *lst_f;
  45. extern FILE *obj_f;
  46.  
  47. /* types */
  48.  
  49. char *nextfield();
  50.  
  51. /* code begins */
  52.  
  53. preparse()
  54. {
  55.     char *sbuf_ptr = statement;        /* pointer to statement    buffer */
  56.     char *field_ptr = NULL;        /* pointer to present field */
  57.     int field_len = 0;             /* length of present scanned field */
  58.     register FLAG state = START;     /* present state */
  59.     FLAG bad_field = NO;
  60.  
  61.     label[0] = label[31] = instr[0] = instr[31]    = NULL;
  62.     opfld_ptr = NULL;
  63.     stmnt_ptr = statement;        /* init for get_source() */
  64.  
  65. /* LIM_C:    'A'-'Z','a'-'z','.'    */
  66. /* LM_C:    '0'-'9','_',?'-'?,'$'    */
  67. /* LBLTRM_C:    ':'            */
  68. /* WS_C:    ' ','\t'        */
  69. /* STMEND_C:    '\n'            */
  70. /* CMNT_C:    '*'            */
  71. /* ILGL_C:    <anything else>     */
  72.  
  73. /* START state */
  74.  
  75.     switch (nextc(&sbuf_ptr)) {
  76.     case CMNT_C:
  77.     case STMEND_C:
  78.     opfld_ptr = statement;        /* operands or comment */
  79.     return COMMENT;            /* nothing here... */
  80.     case ILGL_C:            /* illegal character */
  81.     case LM_C:              /* LM_C's can't start label */
  82.     label[31] = YES;        /* bad label char in label field */
  83.     case LIM_C:
  84.     field_ptr = sbuf_ptr - 1;    /* nextc already inc. sbuf_ptr */
  85.     ++field_len;            /* got 1 so far */
  86.     state = LBL;            /* enter LBL state */
  87.     break;
  88.     case WS_C:
  89.     field_ptr = nextfield(&sbuf_ptr);    /* skip the white space */
  90.     if (*field_ptr == '*' || *field_ptr == '\n') {
  91.         opfld_ptr = statement;        /* operands or comment */
  92.         return COMMENT;
  93.     }
  94.     state = LIM;
  95.     break;                    /* try again */
  96.     }
  97.  
  98. /* LBL state */
  99.  
  100.     while (state == LBL) {
  101.     switch(nextc(&sbuf_ptr)) {
  102.     case ILGL_C:
  103.         label[31] = YES;            /* got a bad char */
  104.     case LIM_C:
  105.     case LM_C:
  106.         ++field_len;            /* one more label char */
  107.         continue;                /* still in LBL state */
  108.     case STMEND_C:
  109.         state = STOP;
  110.     case LBLTRM_C:                /* label ended... */
  111.     case WS_C:
  112.         savefield(field_ptr, field_len, label); /* save the label */
  113.         if (state != STOP) {
  114.         field_len = NULL;            /* starting    fresh */
  115.         field_ptr = nextfield(&sbuf_ptr);   /* get a new field */
  116. /**f3*/        state = (*field_ptr == '*') ? STOP : LIM;
  117.         }
  118.     }
  119.     }
  120.  
  121. /* LIM state */
  122.  
  123.     while (state == LIM) {
  124.     switch(nextc(&sbuf_ptr)) {
  125.     case LM_C:
  126.     case LIM_C:
  127.         ++field_len;
  128.         continue;                /* try another */
  129.     case STMEND_C:
  130.     case WS_C:
  131.         state = STOP;
  132.         savefield(field_ptr, field_len,    instr);    /* save legal instr */
  133.         instr[31] = bad_field;
  134.         break;
  135.     case LBLTRM_C:
  136.         savefield(field_ptr, field_len,    label);    /* save label */
  137.         label[31] = bad_field;
  138.         bad_field = field_len = NULL;        /* going for instr */
  139.         field_ptr = nextfield(&sbuf_ptr);    /* look for it */
  140.         continue;                /* still LIM state */
  141.     case ILGL_C:
  142.         bad_field = YES;            /* bad char */
  143.         ++field_len;
  144.         continue;                /* try another */
  145.     }
  146.     }
  147.  
  148.  
  149. /* STOP state */
  150.  
  151.     nextfield(&sbuf_ptr);                /* get to next field */
  152.     opfld_ptr =  sbuf_ptr;                /* operands    or comment */
  153.     return OK;
  154. }
  155.  
  156. /* return type of char pointed to, bump pointer    */
  157.  
  158. nextc(ptr)
  159. register char **ptr;
  160. {
  161.     register char c;
  162.  
  163.     c = *(*ptr)++;  /* get the buf ptr, post inc., get char it points to */
  164.     if (isalpha(c) || (c == '.'))
  165.     return LIM_C;
  166.     if (isdigit(c) || (c == '_') || (c == '$'))
  167.     return LM_C;            /** || (c == '-') ??? **/
  168.     switch (c) {
  169.     case '\n':  return STMEND_C;
  170.     case ' ':
  171.     case '\t':  return WS_C;
  172.     case ':':   return LBLTRM_C;
  173.     case '*':   return CMNT_C;
  174.     default:    return ILGL_C;
  175.     }
  176. }
  177.  
  178. /* align pointer on next char other than ' ' or '\t' */
  179.  
  180. char *nextfield(ptr)
  181. register char **ptr;
  182. {
  183.     if (!**ptr)    return --(*ptr);
  184.     while                /* skips too much...? */
  185.     /*if*/ ((**ptr == ' ') || (**ptr == '\t'))
  186.     ++(*ptr);            /* bump buf ptr ???*/
  187.     return *ptr;            /* value of ptr ???*/
  188. }
  189.  
  190. /***
  191.     get a line of text into statement.    Allows nesting of source files and
  192.     input from stdin.
  193. ***/
  194.  
  195. char *
  196. nextline()
  197. {                        /* get a line into buffer */
  198.     while (!fgets(statement, STMNT_SIZE, _src[src_level])) {
  199.     if (src_level) {            /* in an included file */
  200.         fclose(_src[src_level--]);        /* close file, pop stack */
  201.         continue;                /* try level above */
  202.     }   
  203.     if (++pass > 2) return NULL;        /* end second pass main file */
  204.     loc_counter = loc_plus = 0;         /* set counter to default */
  205.     line_count = 0;             /* rewind for second pass */
  206.     for ( ; src_level; fclose(_src[src_level--]));/* close include files */
  207.     fseek(_src[0], 0L, 0);          /* rewind the source file */
  208.     /* err_out(FLUSH); */            /* get rid of pending errors */
  209.     continue;                /* start second pass */
  210.     }
  211.     ++line_count;                /* count the line */
  212.     return statement;                /* anything    but NULL would work */
  213. }
  214.  
  215. /* save the field pointed to by ptr, max field length is 30 + NULL */
  216.  
  217. savefield(ptr, len, dest)
  218. register char *ptr;
  219. int len;
  220. register char *dest;
  221. {
  222.     register int x;
  223.     for (x = 30; x && len; --x, --len)        /* dec. x and len each time */
  224.     *dest++    = *ptr++;
  225.     *dest = '\0';            /* terminate string */
  226. }
  227.  
  228. /*** aztec can't...
  229. #undef START
  230. #undef LBL
  231. #undef LIM
  232. #undef STOP
  233.  
  234. #undef LIM_C
  235. #undef LM_C
  236. #undef LBLTRM_C
  237. #undef WS_C
  238. #undef STMEND_C
  239. #undef CMNT_C
  240. #undef ILGL_C
  241. ***/                            /* end of preparse() */
  242.  
  243. /***
  244.     send data for present line here, dump when appropriate
  245.  
  246. line format:
  247.  
  248.      1         2         3         4     5         6         7
  249. 1234567890123456789012345678901234567890123456789012345678901234567890123456789
  250. |  | |    | |  | |       | |       |     |     | |             | |            |
  251. line locval opcd 1st  word 2nd  word     instrct operand field.. .comment field
  252.  
  253. 1234 123456 1234 1234 1234 1234 1234    123456789223456789323456789423456789...
  254.        [---- ---- ---- ---- ----]    [-----------------------------------..]
  255.  
  256. ***/
  257.  
  258. /*
  259.     raw code is sent here as it is produced by the system. this
  260.     function will send it to appropriate places, in the correct    form.
  261. */
  262. /* send buffer to all open list channels */
  263.  
  264. list_dump(buf)
  265. char *buf;
  266. {
  267.     if (nolist)    return;
  268.     if (lcon) puts(buf);
  269.     if (llst) fputs(buf, lst_d);
  270.     if (lfile) fputs(buf, lst_f);
  271. }
  272.  
  273. obj_out(action,    cdp, size)
  274. int action;
  275. char *cdp;
  276. int size;
  277. {
  278.     register int y;
  279.     extern long s_lc;
  280.     extern char s_buf[48];    /* init first char, room to spare */
  281.     extern int s_cnt;        /* bytes in current buffer */
  282.     extern int s_x;        /* index into s_buf */
  283.  
  284.     if (!obj_open) return NULL;         /* put into obj file */
  285.     switch (action) {
  286.     case CODE:
  287.     case DATA:
  288.     s_lc = 0L;
  289.     case MDATA:
  290. top:
  291.     for (y = 0; size && (s_cnt < 16); --size,    ++s_cnt) {
  292. /**f4*/        lcksm += cdp[y++];                /* line checksum */
  293.     }
  294.     hex_byt(s_buf + s_x, cdp, y);            /* get them in buf */
  295.     s_x += y * 2;                     /* bump x */
  296.     s_lc += y;
  297.     if (s_cnt == 16) {                /* time to flush */
  298.         flush_rcrd(s_buf, s_cnt, s_x);
  299.         new_rcrd(s_buf, s_lc, &s_x);
  300.         s_cnt = 0;
  301.         if (size) {                 /* more to buffer */
  302.         cdp += y;                /* skip already    done */
  303.         goto top;
  304.         }
  305.     }
  306.     break;
  307.     case SYNC:
  308. /**f4*/    flush_rcrd(s_buf, s_cnt, s_x);        /* flush s_buf */
  309.     new_rcrd(s_buf,    0L, &s_x);
  310.     s_cnt = 0;
  311.     break;
  312.     case OPEN:
  313.     fputs("S0030000FC\n", obj_f);            /* header record */
  314. /**f4*/    new_